package com.cirnoworks.uhs;

import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.util.concurrent.ArrayBlockingQueue;

public class Packet {

	private static ArrayBlockingQueue<Packet> pool = new ArrayBlockingQueue<Packet>(
			2000);

	public static Packet create(SocketAddress address, ByteBuffer buf) {
		Packet packet;
		packet = pool.poll();
		if (packet == null) {
			packet = new Packet(buf.remaining());
		}
		packet.setup(address, buf);
		return packet;
	}

	private SocketAddress address;
	private ByteBuffer buf;

	private Packet(int cap) {
		buf = ByteBuffer.allocateDirect(cap);
	}

	private void setup(SocketAddress address, ByteBuffer buf) {
		this.address = address;
		if (buf.remaining() > this.buf.capacity()) {
			this.buf = ByteBuffer.allocateDirect(buf.remaining());
		}
		this.buf.clear();
		this.buf.put(buf);
		this.buf.flip();
	}

	public boolean sendTo(DatagramChannel channel) throws IOException {
		if (channel.send(buf, address) > 0) {
			release();
			return true;
		} else {
			return false;
		}
	}

	private void release() {
		pool.offer(this);
	}
}
